package cn.kgc.commons.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * <p>修改SpringCache序列化规则</p>
 *
 * @author 李孟鸠
 * @Date: 2022年11月03日11:50
 */
@Configuration
@EnableCaching
@EnableConfigurationProperties(CacheProperties.class)
public class SpringCacheConfig {

    //改造SpringCache类中使用Redis保存数据时,key和value的序列化的格式
    @Bean
    RedisCacheConfiguration
    redisCacheConfiguration(CacheProperties cacheProperties){

        //获得springCache中Redis缓存的默认配置
        RedisCacheConfiguration configuration=
                RedisCacheConfiguration.defaultCacheConfig();

        //创建Redis的序列化器
        StringRedisSerializer stringRedisSerializer = new
                StringRedisSerializer();

        //创建Redis的序列化器
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =
                new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        //设置Redis缓存key的序列化方式
        configuration=configuration
                .serializeKeysWith(RedisSerializationContext
                        .SerializationPair.fromSerializer(stringRedisSerializer));

        //设置Redis缓存value的序列化方式
        configuration=configuration
                .serializeValuesWith(RedisSerializationContext
                        .SerializationPair.fromSerializer(jackson2JsonRedisSerializer));

        //从cacheProperties中获得配置文件中关于SpringCache的Redis的配置
        CacheProperties.Redis redis= cacheProperties.getRedis();

        if(redis.getTimeToLive()!=null){
            configuration=configuration.entryTtl(redis.getTimeToLive());
        }
        if(redis.getKeyPrefix()!=null){
            configuration=configuration.prefixKeysWith(redis.getKeyPrefix());
        }
        if(!redis.isCacheNullValues()){
            configuration=configuration.disableCachingNullValues();
        }
        if(!redis.isUseKeyPrefix()){
            configuration=configuration.disableKeyPrefix();
        }
        return configuration;
    }

}
